package com.zian.controller.common;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.ArrayUtil;
import com.google.code.kaptcha.Producer;
import com.zian.common.CommonConstant;
import com.zian.common.R;
import com.zian.domain.vo.CaptchaVO;
import com.zian.exception.BadRequestException;
import com.zian.utils.AliOssUtil;
import com.zian.utils.IdUtils;
import com.zian.utils.RedisUtils;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/common")
@RequiredArgsConstructor
public class CommonController {
    @Value("${server.port}")
    private String port;

//    @Value("${upload}")
//    private String uploadPath;

    private final RedisUtils redisUtils;

    private final Producer captchaProducer;

    private final AliOssUtil aliOssUtil;

    // 文件上传
   /* @PostMapping("/upload")
   @ApiOperation("单文件上传")
    public R<String> uploadFileSingle(MultipartFile file) throws UnknownHostException {
        log.info("文件上传，文件名为：{}", file.getOriginalFilename());
        // 生成一个随机的文件名
        String[] split = file.getOriginalFilename().split("\\.");
        String suffix = split[split.length - 1];
        String string = IdUtils.fastSimpleUUID();
        String fileName = string + "." + suffix;
        String otherImgPath = uploadPath;
        // 文件夹
        File dir = new File(otherImgPath);
        // 文件
        File dest = new File(otherImgPath + fileName);
        try {
            if (!dir.exists()) {
                if (!dir.mkdir()) {
                    throw new IOException("创建文件夹失败 ， 路径：" + dir.getName());
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败");
        }
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败");
        }
        InetAddress localHost = InetAddress.getLocalHost();
        String hostAddress = localHost.getHostAddress();
        // 构建一个可访问的图片文件路径
        String url = UrlBuilder.ofHttp("http://" + hostAddress + ":" + port + "/upload/" + fileName, StandardCharsets.UTF_8).build();

        return R.ok(url);
    }

    // 多文件上传
    @PostMapping("/uploads")
   @ApiOperation("多文件上传")
    public R<List<String>> uploadFileMulti(MultipartFile[] files) throws UnknownHostException {
        if (ArrayUtil.isEmpty(files)) throw new BadRequestException("文件不能为空");
        log.info("多文件上传，文件个数为：{}", files.length);
        // 创建文件夹
        File dir = new File(uploadPath);
        try {
            if (!dir.exists()) {
                if (!dir.mkdir()) {
                    throw new IOException("创建文件夹失败 ， 路径：" + dir.getName());
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败");
        }
        ArrayList<String> urls = new ArrayList<>();
        // 生成文件对象
        for (MultipartFile file : files) {
            String[] split = file.getOriginalFilename().split("\\.");
            String suffix = split[split.length - 1];
            String fileName = IdUtils.fastSimpleUUID() + "." + suffix;
            File dest = new File(uploadPath + fileName);
            try {
                file.transferTo(dest);
            } catch (IOException e) {
                throw new RuntimeException("上传文件失败");
            }
            InetAddress localHost = InetAddress.getLocalHost();
            String hostAddress = localHost.getHostAddress();
            urls.add(UrlBuilder.ofHttp("http://" + hostAddress + ":" + port + "/upload/" + fileName, StandardCharsets.UTF_8).build());
        }


        return R.ok(urls);
    }
*/

    @PostMapping("/upload")
   @ApiOperation("单文件上传")
    public R<String> uploadFileSingle(MultipartFile file) throws IOException {
        log.info("文件上传，文件名为：{}", file.getOriginalFilename());
        String fileName = aliOssUtil.generateFileName(file);
        String url = aliOssUtil.upload(file.getBytes(), fileName);
        return R.ok(url);
    }

    @PostMapping("/uploads")
   @ApiOperation("多文件上传")
    public R<List<String>> uploadFileMulti(MultipartFile[] files) throws IOException {
        if (ArrayUtil.isEmpty(files)) throw new BadRequestException("文件不能为空");
        log.info("多文件上传，文件个数为：{}", files.length);
        List<String> urls = aliOssUtil.uploadArrayFile(files);
        return R.ok(urls);
    }


    // 获取验证码

    @GetMapping("/captchaImage")  // 生成一个4位的字符验证码
   @ApiOperation("获取验证码")
    public R<CaptchaVO> getCode() {

        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        // key 和 验证的结果 的组合存储到 redis中 ,
        String verifyKey = CommonConstant.CAPTCHA_KEY + uuid;

        BufferedImage image = null;
        String capText = captchaProducer.createText();
        // 将表达式算式转换为图片对象
        image = captchaProducer.createImage(capText);
        log.info("验证码算式：" + capText + "  验证码结果：" + capText);
        redisUtils.setCacheObject(verifyKey, capText, 120, TimeUnit.SECONDS);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            // 将图片转换为二进制流
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            return R.error(e.getMessage());
        }
        CaptchaVO vo = new CaptchaVO();
        vo.setUuid(uuid);
        // 利用hutool将图片转换为base64
        vo.setCaptchaImage(Base64.encode(os.toByteArray()));
        return R.ok(vo);
    }


}
